//-------------------------------------------------------------------------------------
// <copyright file="TransportInfo.cs" company="Microsoft">
//      Copyright (c) 2003 Microsoft Corporation. All rights reserved.
//      THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
//      EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
//      WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// </copyright>
// <summary>
//      Holds information about a transport, often known as an adapter.
// </summary>  
//-------------------------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks.BizTalk2004.Configuration
{
	#region Using directives

    using System;

	#endregion

	/// <summary>
	/// Holds information about a particular instance of a transport, often known as an adapter.
	/// </summary>
	internal class TransportInfo : BizTalkConfigurableEntityBase
	{
		#region Member Variables

        private string address;
        private NotificationTypes deliveryNotification = NotificationTypes.None;
        private bool orderedDelivery = false;
        private bool isPrimary = false;
        private int retryCount = 3;
        private int retryInterval = 5;
		private SendPort sendPort;
        private Protocol protocol;
        private TransportData transportData = new TransportData();
        private ServiceWindow serviceWindow;

		#endregion

		#region Constructors

		/// <summary>
		/// Creates a new transport info with default properties.
		/// </summary>
		/// <param name="port">
		/// The send port that the transport info will belong to.
		/// </param>
		/// <param name="primary">
		/// <b>true</b> if this is a primary transport, or <b>false</b> if it is a secondary transport.
		/// </param>
		public TransportInfo(SendPort port, bool primary)
			: base(port.Installation, null)
		{
			this.isPrimary = primary;
			this.sendPort = port;
		}

		#endregion

		#region Properties

		/// <summary>
		/// Gets or sets the address, often known as the URI.
		/// </summary>
		/// <value>
		/// The address, often known as the URI.
		/// </value>
		public string Address
		{
			get 
			{ 
				return this.address; 
			}
			set 
			{ 
				this.address = value; 
			}
		}

		/// <summary>
		/// Gets or sets the transport data to initialize this adapter. If using one of the derived classes from
		/// <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.TransportData"/> then you should use the one that
		/// matches the specified protocol.
		/// </summary>
		/// <value>
		/// A <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.TransportData"/>.
		/// </value>
        public TransportData TransportData
        {
            get 
			{ 
				return this.transportData; 
			}
            set 
			{ 
				this.transportData = value; 
			}
        }

		/// <summary>
		/// Gets or sets the protocol used by this transport.
		/// </summary>
		/// <value>
		/// A <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.Protocol"/>. 
		/// </value>
        public Protocol Protocol
        {
            get 
			{ 
				return this.protocol; 
			}
            set 
			{ 
				this.protocol = value; 
			}
        }

		/// <summary>
		/// Gets whether this transport is a primary transport.
		/// </summary>
		/// <value>
		/// <b>true</b> if the transport is primary, or <b>false</b> if it is secondary.
		/// </value>
        public bool IsPrimary
        {
            get 
			{ 
				return this.isPrimary; 
			}
        }

		/// <summary>
		/// Gets or sets whether this transport supports ordered delivery of messages.
		/// </summary>
		/// <value>
		/// <b>true</b> if the transport supports ordered delivery, or <b>false</b> otherwise.
		/// </value>
        public bool OrderedDelivery
        {
            get 
			{ 
				return this.orderedDelivery; 
			}
            set 
			{ 
				this.orderedDelivery = value; 
			}
        }

		/// <summary>
		/// Gets or sets the number of retries to send or receive a message.
		/// </summary>
		/// <value>
		/// The number of retries to send or receive a message.
		/// </value>
        public int RetryCount
        {
            get 
			{ 
				return this.retryCount; 
			}
            set 
			{ 
				this.retryCount = value; 
			}
        }

		/// <summary>
		/// Gets or sets the interval between retries; the units of this may vary between different adapters
		/// however minutes is the most common.
		/// </summary>
		/// <value>
		/// The interval between retries in units defined by the actual adapter.
		/// </value>
        public int RetryInterval
        {
            get 
			{ 
				return this.retryInterval; 
			}
            set 
			{ 
				this.retryInterval = value; 
			}
        }

		/// <summary>
		/// Gets the send port that this transport info belongs to.
		/// </summary>
		/// <value>
		/// A <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.SendPort"/>.
		/// </value>
		public SendPort SendPort
		{
			get
			{
				return this.sendPort;
			}
		}

		/// <summary>
		/// Gets or sets the service window that this transport is enabled in.
		/// </summary>
		/// <value>
		/// A <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.ServiceWindow"/>.
		/// </value>
        public ServiceWindow ServiceWindow
        {
            get 
			{ 
				//if people access this while it is null we will create a new one so that they don't get
				//null reference exceptions if they just try to set properties on it
				if (this.serviceWindow == null)
				{
					this.serviceWindow = new ServiceWindow(false);
				}
				return this.serviceWindow; 
			}
            set 
			{ 
				this.serviceWindow = value; 
			}
        }

		#endregion

		#region Static Methods

		/// <summary>
		/// Creates a new transport info based on the properties of an existing transport.
		/// </summary>
		/// <param name="port">
		/// The <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.SendPort"/> that the transport belongs to.
		/// </param>
		/// <param name="primary">
		/// <b>true</b> to load the primary transport, or <b>false</b> to load the secondary transport.
		/// </param>
		public static TransportInfo Load(SendPort port, bool primary)
		{
			//get the actual port and transport
			BtsSendPort actualPort = port.Installation.CatalogExplorer.SendPorts[port.Name];
			BtsTransportInfo actualTransport = (primary) ? actualPort.PrimaryTransport : actualPort.SecondaryTransport;
			if (actualTransport == null)
			{
				throw new ArgumentException("The specified transport does not exist.", "primary");
			}

			//create a new one
			TransportInfo info = new TransportInfo(port, primary);
			info.address = actualTransport.Address;
			info.deliveryNotification = (NotificationTypes)(int)actualTransport.DeliveryNotification;
			info.orderedDelivery = actualTransport.OrderedDelivery;
			info.isPrimary = primary;
			info.protocol = port.Installation.Protocols[actualTransport.TransportType.Name];
			info.retryCount = actualTransport.RetryCount;
			info.retryInterval = actualTransport.RetryInterval;
			info.sendPort = port;
			info.transportData = new TransportData(actualTransport.TransportTypeData);
			info.serviceWindow = new ServiceWindow(actualTransport.ServiceWindowEnabled, actualTransport.ToTime, actualTransport.FromTime);
			return info;
		}

		#endregion

		#region Methods

		/// <summary>
		/// Saves the transport information.
		/// </summary>
		protected internal override void SaveImpl()
		{  
			//get the actual port and transport
			BtsSendPort actualPort = this.Installation.CatalogExplorer.SendPorts[this.sendPort.Name];
			BtsTransportInfo actualTransport = (this.isPrimary) ? actualPort.PrimaryTransport : actualPort.SecondaryTransport;

			//save the details - we do not save IsPrimary and SendPort
			actualTransport.Address = this.address;
			actualTransport.DeliveryNotification = (NotificationTypes)(int)this.deliveryNotification;
			actualTransport.OrderedDelivery = this.orderedDelivery;
			actualTransport.TransportType = this.Installation.CatalogExplorer.ProtocolTypes[this.protocol.Name];
			actualTransport.RetryCount = this.retryCount;
			actualTransport.RetryInterval = this.retryInterval;
			if (this.transportData != null)
			{
				actualTransport.TransportTypeData = this.transportData.GetTransportXml();
			}
			else
			{
				actualTransport.TransportTypeData = null;
			}
			if (this.serviceWindow != null)
			{
				actualTransport.ServiceWindowEnabled = this.serviceWindow.Enabled;
				actualTransport.FromTime = this.serviceWindow.StartTime;
				actualTransport.ToTime = this.serviceWindow.EndTime;
			}
			else
			{
				actualTransport.ServiceWindowEnabled = false;
			}
		}

		#endregion
	}
}

